#include "arraystackwindow.h"
#include <QPainter>
#include <QDialog>
#include <QDialogButtonBox>
#include <QVBoxLayout>
#include <QFormLayout>

ArrayStackWindow::ArrayStackWindow(QWidget *parent)
    : QMainWindow(parent), m_stackArray(nullptr), m_capacity(0), m_top(-1)
{
    setupUI();
    updateDisplay();
}

ArrayStackWindow::~ArrayStackWindow()
{
    // 释放动态数组内存
    delete[] m_stackArray;
}

void ArrayStackWindow::setupUI()
{
    setWindowTitle("顺序栈可视化演示");
    setMinimumSize(1000, 600);

    QWidget *centralWidget = new QWidget(this);
    setCentralWidget(centralWidget);

    QHBoxLayout *mainLayout = new QHBoxLayout(centralWidget);

    // 左侧：可视化部分
    QVBoxLayout *leftLayout = new QVBoxLayout();
    QLabel *visualLabel = new QLabel("栈结构可视化:");
    visualLabel->setStyleSheet("font-weight: bold; font-size: 14px;");
    leftLayout->addWidget(visualLabel);
    mainLayout->addLayout(leftLayout, 2);

    // 右侧：操作和信息部分
    QVBoxLayout *rightLayout = new QVBoxLayout();
    rightLayout->setSpacing(15);

    // 返回按钮
    QPushButton *returnBtn = new QPushButton("返回主菜单");
    returnBtn->setStyleSheet("QPushButton { background-color: #f0f0f0; border: 1px solid #ccc; padding: 8px; }");
    rightLayout->addWidget(returnBtn);

    // 操作按钮组
    QGroupBox *opsGroup = new QGroupBox("栈操作");
    opsGroup->setStyleSheet("QGroupBox { font-weight: bold; }");
    QVBoxLayout *opsLayout = new QVBoxLayout(opsGroup);
    opsLayout->setSpacing(10);

    // 初始化栈按钮
    QPushButton *inputBtn = new QPushButton("初始化栈容量");
    inputBtn->setToolTip("设置栈的最大容量");

    // 入栈操作
    QHBoxLayout *pushLayout = new QHBoxLayout();
    m_pushEdit = new QLineEdit();
    m_pushEdit->setPlaceholderText("输入入栈元素");
    QPushButton *pushBtn = new QPushButton("入栈");
    pushLayout->addWidget(m_pushEdit);
    pushLayout->addWidget(pushBtn);

    // 其他操作按钮
    QPushButton *popBtn = new QPushButton("出栈");
    QPushButton *peekBtn = new QPushButton("获取栈顶");
    QPushButton *clearBtn = new QPushButton("清空栈");
    QPushButton *demoBtn = new QPushButton("演示操作");

    // 将所有按钮添加到操作面板
    opsLayout->addWidget(inputBtn);
    opsLayout->addLayout(pushLayout);
    opsLayout->addWidget(popBtn);
    opsLayout->addWidget(peekBtn);
    opsLayout->addWidget(clearBtn);
    opsLayout->addWidget(demoBtn);

    // 信息显示部分
    QGroupBox *infoGroup = new QGroupBox("栈信息");
    infoGroup->setStyleSheet("QGroupBox { font-weight: bold; }");
    QVBoxLayout *infoLayout = new QVBoxLayout(infoGroup);
    m_display = new QTextEdit();
    m_display->setReadOnly(true);
    m_display->setMaximumHeight(200);
    infoLayout->addWidget(m_display);

    // 将操作面板和信息显示添加到右侧布局
    rightLayout->addWidget(opsGroup);
    rightLayout->addWidget(infoGroup);

    mainLayout->addLayout(rightLayout, 1);

    // 连接信号槽
    connect(inputBtn, &QPushButton::clicked, this, &ArrayStackWindow::onInputData);
    connect(pushBtn, &QPushButton::clicked, this, &ArrayStackWindow::onPush);
    connect(popBtn, &QPushButton::clicked, this, &ArrayStackWindow::onPop);
    connect(peekBtn, &QPushButton::clicked, this, &ArrayStackWindow::onPeek);
    connect(clearBtn, &QPushButton::clicked, this, &ArrayStackWindow::onClear);
    connect(demoBtn, &QPushButton::clicked, this, &ArrayStackWindow::onDemo);
    connect(returnBtn, &QPushButton::clicked, this, &ArrayStackWindow::onReturnToMainMenu);
}

void ArrayStackWindow::paintEvent(QPaintEvent* event)
{
    Q_UNUSED(event);

    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.fillRect(rect(), Qt::white);

    if (m_stackArray == nullptr) {
        painter.setPen(Qt::black);
        painter.drawText(rect(), Qt::AlignCenter, "请先初始化栈容量");
        return;
    }

    drawStack(painter);
}

void ArrayStackWindow::drawStack(QPainter& painter)
{
    painter.setPen(QPen(Qt::black, 2));
    QFont font = painter.font();
    font.setPointSize(12);
    painter.setFont(font);

    // 计算栈可视化区域的中心位置
    int centerX = width() * 0.35; // 向左移动，更靠近中心
    int startY = 100;
    int cellWidth = 80;
    int cellHeight = 40;
    int spacing = 5;

    // 计算栈的总高度
    int stackHeight = m_capacity * (cellHeight + spacing);

    // 调整起始Y位置，使栈在垂直方向居中
    startY = (height() - stackHeight) / 2;
    if (startY < 50) startY = 50; // 确保不会太靠上

    // 绘制栈标题
    painter.drawText(centerX - 40, startY - 30, "顺序栈结构");

    // 绘制栈顶指针
    painter.setPen(QPen(Qt::red, 2));
    painter.drawText(centerX - 120, startY + (m_capacity - m_top - 1) * (cellHeight + spacing) + cellHeight / 2 + 5,
                     QString("top →"));

    // 绘制栈框架
    painter.setPen(QPen(Qt::black, 2));
    for (int i = 0; i < m_capacity; i++) {
        int y = startY + (m_capacity - i - 1) * (cellHeight + spacing);

        // 绘制单元格
        painter.drawRect(centerX, y, cellWidth, cellHeight);

        // 绘制索引
        painter.drawText(centerX - 30, y + cellHeight / 2 + 5, QString("[%1]").arg(i));

        // 绘制数据（如果有）
        if (i <= m_top) {
            painter.setBrush(QBrush(QColor(173, 216, 230)));
            painter.drawRect(centerX, y, cellWidth, cellHeight);
            painter.setBrush(Qt::NoBrush);

            painter.drawText(centerX + 10, y + cellHeight / 2 + 5, QString::number(m_stackArray[i]));

            // 高亮当前栈顶
            if (i == m_top) {
                painter.setPen(QPen(Qt::red, 3));
                painter.drawRect(centerX, y, cellWidth, cellHeight);
                painter.setPen(QPen(Qt::black, 2));
            }
        }
    }

    // 绘制栈底和栈顶标记
    painter.drawText(centerX + cellWidth + 10, startY + (m_capacity - 1) * (cellHeight + spacing) + cellHeight / 2 + 5, "栈底");
    painter.drawText(centerX + cellWidth + 10, startY + (m_capacity - m_top - 1) * (cellHeight + spacing) + cellHeight / 2 + 5, "栈顶");
}

void ArrayStackWindow::onReturnToMainMenu()
{
    emit returnToMainMenu();
    this->close();
}

void ArrayStackWindow::updateDisplay()
{
    QString info = "栈状态信息:\n\n";

    if (m_stackArray == nullptr) {
        info += "栈未初始化，请先设置栈容量";
    } else {
        info += QString("栈容量: %1\n").arg(m_capacity);
        info += QString("栈顶位置: %1\n").arg(m_top);
        info += QString("当前元素个数: %1\n\n").arg(m_top + 1);

        if (m_top == -1) {
            info += "栈为空";
        } else {
            info += "栈内容 (从栈底到栈顶):\n";
            for (int i = 0; i <= m_top; i++) {
                info += QString("[%1] = %2").arg(i).arg(m_stackArray[i]);
                if (i == m_top) {
                    info += "  ← 栈顶";
                }
                info += "\n";
            }
        }
    }

    m_display->setText(info);
    update(); // 触发重绘
}

void ArrayStackWindow::onInputData()
{
    QDialog dialog(this);
    dialog.setWindowTitle("初始化栈容量");
    dialog.setFixedSize(300, 120);

    QVBoxLayout *mainLayout = new QVBoxLayout(&dialog);

    QLabel *label = new QLabel("请输入栈容量:");
    m_inputEdit = new QLineEdit();
    m_inputEdit->setPlaceholderText("正整数");

    QDialogButtonBox *buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);

    mainLayout->addWidget(label);
    mainLayout->addWidget(m_inputEdit);
    mainLayout->addWidget(buttons);

    connect(buttons, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);
    connect(buttons, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);

    if (dialog.exec() == QDialog::Accepted) {
        QString input = m_inputEdit->text();
        if (input.isEmpty()) {
            QMessageBox::warning(this, "输入错误", "请输入栈容量");
            return;
        }

        bool ok;
        int capacity = input.toInt(&ok);
        if (ok && capacity > 0) {
            // 释放原有数组
            delete[] m_stackArray;

            // 创建新数组
            m_stackArray = new int[capacity];
            m_capacity = capacity;
            m_top = -1;

            updateDisplay();
            QMessageBox::information(this, "初始化成功", QString("栈容量设置为 %1").arg(capacity));
        } else {
            QMessageBox::warning(this, "输入错误", "请输入有效的正整数");
        }
    }
}

void ArrayStackWindow::onPush()
{
    if (m_stackArray == nullptr) {
        QMessageBox::warning(this, "错误", "请先初始化栈容量");
        return;
    }

    if (m_top >= m_capacity - 1) {
        QMessageBox::warning(this, "栈满", "栈已满，无法执行入栈操作");
        return;
    }

    QString input = m_pushEdit->text();
    if (input.isEmpty()) {
        QMessageBox::warning(this, "输入错误", "请输入要入栈的值");
        return;
    }

    bool ok;
    int value = input.toInt(&ok);
    if (ok) {
        m_stackArray[++m_top] = value;
        m_pushEdit->clear();
        updateDisplay();
        QMessageBox::information(this, "入栈成功", QString("元素 %1 已入栈").arg(value));
    } else {
        QMessageBox::warning(this, "输入错误", "请输入有效的整数");
    }
}

void ArrayStackWindow::onPop()
{
    if (m_stackArray == nullptr) {
        QMessageBox::warning(this, "错误", "请先初始化栈容量");
        return;
    }

    if (m_top < 0) {
        QMessageBox::warning(this, "栈空", "栈为空，无法执行出栈操作");
        return;
    }

    int value = m_stackArray[m_top--];
    updateDisplay();
    QMessageBox::information(this, "出栈成功", QString("出栈元素: %1").arg(value));
}

void ArrayStackWindow::onPeek()
{
    if (m_stackArray == nullptr) {
        QMessageBox::warning(this, "错误", "请先初始化栈容量");
        return;
    }

    if (m_top < 0) {
        QMessageBox::information(this, "栈顶元素", "栈为空");
        return;
    }

    int value = m_stackArray[m_top];
    QMessageBox::information(this, "栈顶元素", QString("栈顶元素: %1").arg(value));
}

void ArrayStackWindow::onClear()
{
    if (m_stackArray == nullptr) {
        QMessageBox::warning(this, "错误", "请先初始化栈容量");
        return;
    }

    QMessageBox::StandardButton reply;
    reply = QMessageBox::question(this, "确认清空", "确定要清空栈吗？",
                                  QMessageBox::Yes | QMessageBox::No);
    if (reply == QMessageBox::Yes) {
        m_top = -1;
        updateDisplay();
        QMessageBox::information(this, "清空成功", "栈已清空");
    }
}

void ArrayStackWindow::onDemo()
{
    if (m_stackArray == nullptr) {
        QMessageBox::warning(this, "错误", "请先初始化栈容量");
        return;
    }

    // 清空栈
    m_top = -1;

    // 演示操作：入栈几个元素
    // 使用简单的随机数生成（不使用std库）
    static unsigned int seed = 12345; // 简单种子

    int demoCount = (m_capacity < 5) ? m_capacity : 5; // 最多演示5个元素

    for (int i = 0; i < demoCount; i++) {
        // 简单伪随机数生成
        seed = (seed * 1103515245 + 12345) & 0x7FFFFFFF;
        int randomValue = (seed % 100) + 1; // 1-100的随机数

        m_stackArray[++m_top] = randomValue;
    }

    updateDisplay();
    QMessageBox::information(this, "演示完成", QString("已自动添加 %1 个随机元素").arg(demoCount));
}
